package xml;

import java.io.File;
import java.io.FileWriter;
import java.text.SimpleDateFormat;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Comment;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

import org.w3c.dom.Text;

public class XmlUtil {

	public static SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
	
	public static  Document getNewDocument(){
		try{
	        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
	        DocumentBuilder docBuilder = factory.newDocumentBuilder();
	        Document doc = docBuilder.newDocument();
	        return doc;
	    }catch(Exception e){
	    	System.out.println("Error al crear un nuevo documento. " + e);
	    	return null;
	    }
	}
	
	public static Node getRootNode(String archivo){
		Node nodoRaiz = null;
		
		Document doc = XmlUtil.getDocument(archivo);
		if (doc != null) {
			nodoRaiz = doc.getDocumentElement();
		}
		
		return nodoRaiz;
	}
	
	public static  Document getDocument(String archivo){
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder;

		try {
			builder = factory.newDocumentBuilder();
			Document document = builder.parse(archivo);
			return document;
		} catch (Exception e) {
			System.out.println("Error al obtener el documento: " + archivo + ". " + e);
			return null;
		}
	}

	public static boolean saveDocument(Node nodoRaiz, String archivo) {
		Document doc = nodoRaiz.getOwnerDocument();
		return XmlUtil.saveDocument(doc, archivo);
	}
	
	public static boolean saveDocument(Document doc, String archivo){
		TransformerFactory tranFactory = TransformerFactory.newInstance(); 
	    Transformer tran;
		try {
			
			tran = tranFactory.newTransformer();
			Source src = new DOMSource(doc); 
		    Result dest = new StreamResult(new FileWriter(new File(archivo)));
		    tran.transform(src, dest); 
		    return true;
		} catch (Exception e) {
			System.out.println("Error al guardar el documento: " + archivo + ". " + e);
			return false;
		}
	}
	
	public static Node createRootNode(String name) {
		Document doc = XmlUtil.getNewDocument();
		Element node = doc.createElement(name);
		doc.appendChild(node);
		
		return node;
	}
	
	public static boolean addAttribute(Node node, String attributeName, Object attributeValue) {
		if (node.getNodeType() == Node.ELEMENT_NODE) {
			Element element = (Element)node;
			element.setAttribute(attributeName, attributeValue.toString());
			return true;
		}
		return false;
	}
	
	public static String getAttributeValue(Node node, String attributeName) {
		if (node.getNodeType() == Node.ELEMENT_NODE) {
			Element element = (Element)node;
			return element.getAttribute(attributeName);
		}
		return null;
	}
	
	public static Node addChild(Node parenNode, String childName, Object childValue) throws Exception {
		Element node = null;
		
		if (parenNode != null) {
			Document doc = parenNode.getOwnerDocument();
			node = doc.createElement(childName);
			
			if (childValue != null) {
				Text t = doc.createTextNode(childValue.toString());
				node.appendChild(t);
			}
			parenNode.appendChild(node);
		} else {
			throw new Exception("Nodo padre no puede ser nulo!");
		}
		
		return node;
	}
	
	public static String getChildNodeValueWithName(Node node, String childName) {
		
		Node childNode = XmlUtil.getChildNodeWithName(node, childName);
		if (childNode != null) {
			Node textNode = childNode.getFirstChild();
			if (textNode.getNodeType() == Node.TEXT_NODE) {
				Text text = (Text)textNode;
				return text.getData();
			}
		}
        return null;
	}
	
	public static Node getChildNodeWithName(Node node, String childName) {
		Node retVal = null;
		
		if (node.getNodeType() == Node.ELEMENT_NODE) {
			Element element = (Element)node;
			retVal = element.getElementsByTagName(childName).item(0);
		}
		
		return retVal;
	}
	
	public static void addComment(Node node, String comment) {
		Document doc = node.getOwnerDocument();
		Comment com = doc.createComment(comment);
		node.appendChild(com);
	}
}
